//
//  EDSUtility.m
//  DrivieSchoolStudents
//
//  Created by TangBin on 2019/5/22.
//  Copyright © 2019 班文政. All rights reserved.
//

#import "EDSUtility.h"
#import <AVFoundation/AVFoundation.h>
#import "TYZCommonCellModel.h"
#import "TYZBaseNavigationController.h"

@implementation EDSUtility


+ (id)objectForKey:(NSString *)key
{
    if ([objectNull(key) isEqualToString:@""]) {
        return nil;
    }
    return [TYZUserDefault objectForKey:key];
}

+ (void)setObject:(id)value forKey:(NSString *)key
{
    if ([objectNull(key) isEqualToString:@""]) {
        return;
    }
    [TYZUserDefault setObject:value forKey:key];
    [TYZUserDefault synchronize];
}

+ (void)removeObjectForKey:(NSString *)key
{
    if ([objectNull(key) isEqualToString:@""]) {
        return;
    }
    [TYZUserDefault removeObjectForKey:key];
    [TYZUserDefault synchronize];
}

+ (NSString *)getMMSSFromSS:(NSInteger)totalTime
{
    
//    NSInteger seconds = //[totalTime integerValue];
    
    //format of hour
    NSString *str_hour = [NSString stringWithFormat:@"%02ld",(long)(totalTime/3600)];
    //format of minute
    NSString *str_minute = [NSString stringWithFormat:@"%02ld",(long)((totalTime%3600)/60)];
    //format of second
    NSString *str_second = [NSString stringWithFormat:@"%02ld",totalTime%60];
    //format of time
    NSString *format_time = [NSString stringWithFormat:@"%@:%@:%@",str_hour,str_minute,str_second];
    
    return format_time;
}

+ (NSString *)getVideoCachePath
{
    NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *videoCache = [docPath stringByAppendingPathComponent:@"videos"] ;
    BOOL isDir = NO;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL existed = [fileManager fileExistsAtPath:videoCache isDirectory:&isDir];
    if ( !(isDir == YES && existed == YES) ) {
        [fileManager createDirectoryAtPath:videoCache withIntermediateDirectories:YES attributes:nil error:nil];
    };
    return videoCache;
}

+ (CGFloat)getFileSize:(NSString *)path
{
    NSFileManager *fileManager = [[NSFileManager alloc] init];
    float filesize = -1.0;
    if ([fileManager fileExistsAtPath:path])
    {
        NSDictionary *fileDic = [fileManager attributesOfItemAtPath:path error:nil];//获取文件的属性
        unsigned long long size = [[fileDic objectForKey:NSFileSize] longLongValue];
        filesize = 1.0*size/1024;
    }
    return filesize;
}

+ (CGFloat)getVideoLength:(NSURL *)URL
{
    NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
                                                     forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
    AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:URL options:opts];
    float second = 0;
    second = urlAsset.duration.value/urlAsset.duration.timescale;
    return second;
}

/**
 删除文件
 
 @param url url description
 */
+ (void)removeWithLocalFile:(NSURL *)url
{
    NSFileManager *fm = [NSFileManager defaultManager];
    BOOL exist = [fm fileExistsAtPath:url.path];
    NSError *error;
    if (exist)
    {
        [fm removeItemAtURL:url error:&error];
    }
}

+ (UIImage *)firstFrameWithVideoURL:(NSURL *)url size:(CGSize)size
{
    // 获取视频第一帧
    NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
    AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:url options:opts];
    AVAssetImageGenerator *generator = [AVAssetImageGenerator assetImageGeneratorWithAsset:urlAsset];
    generator.appliesPreferredTrackTransform = YES;
    if (size.width != 0)
    {
        generator.maximumSize = CGSizeMake(size.width, size.height);
    }
    NSError *error = nil;
    CGImageRef img = [generator copyCGImageAtTime:CMTimeMake(0, 10) actualTime:NULL error:&error];
    UIImage *image = [UIImage imageWithCGImage:img];
    CGImageRelease(img);
    return image;
}

/**
 进入登录页面
 
 @param presentVC presentVC description
 @param completion completion description
 */
+ (void)presentLoginVC:(UIViewController *)presentVC animated:(BOOL)animated completion:(void (^)(void))completion
{
    /*
    [[NSNotificationCenter defaultCenter] postNotificationName:kUSER_COME_IN_LOGIN_HIDDEN_TIPS_NOTI object:nil];
    
    UIViewController *loginVC = [[TYZRouter sharedInstance] getLoginVC:nil];
    TYZBaseNavigationController *loginNav = [[TYZBaseNavigationController alloc] initWithRootViewController:loginVC];
    [TYZJumpVCManager presentBaseVC:presentVC presentVC:loginNav animated:animated completion:completion];
     */
}

/**
 拼接http地址
 
 @param url url description
 @return return value description
 */
+ (NSString *)joinHttpUrl:(NSString *)url
{
    if ([objectNull(url) isEqualToString:@""])
    {
        return @"";
    }
    NSString *allUrl = @"";
    if ([url hasPrefix:@"http"])
    {
        allUrl = url;
    }
    else if ([url hasPrefix:@"/"])
    {
        allUrl = [NSString stringWithFormat:@"%@%@", kBaseUrl, [url stringByURLEncode]];
    }
    else
    {
        allUrl = [NSString stringWithFormat:@"%@/%@", kBaseUrl, [url stringByURLEncode]];
//        allUrl = [kBaseUrl stringByAppendingPathComponent:url];
    }
    return allUrl;
}

/// 拼接图片http地址
/// @param url url description
+ (NSString *)joinImageHttpUrl:(NSString *)url
{
    /*
    if ([objectNull(url) isEqualToString:@""])
        {
            return @"";
        }
        NSString *allUrl = @"";
        if ([url hasPrefix:@"http"])
        {
            allUrl = url;
        }
        else if ([url hasPrefix:@"/"])
        {
            allUrl = [NSString stringWithFormat:@"%@%@", [EDSAppDelegateTool sharedInstance].userInfoModel.imgServiceUrl, [url stringByURLEncode]];
        }
        else
        {
            allUrl = [NSString stringWithFormat:@"%@/%@", [EDSAppDelegateTool sharedInstance].userInfoModel.imgServiceUrl, [url stringByURLEncode]];
    //        allUrl = [kBaseUrl stringByAppendingPathComponent:url];
        }
        return allUrl;
     */
    return @"";
}

/**
 删除根地址
 
 @param url 带有根地址的地址
 @return return value description
 */
+ (NSString *)removeBaseUrl:(NSString *)url
{
    return [url stringByReplacingOccurrencesOfString:kBaseUrl withString:@""];
}

/**
 改变图片透明度 渐变
 
 @return return value description
 */
+ (CAGradientLayer *)changeImageAlpha:(CGRect)bounds
{
    CAGradientLayer *gradLayer = [CAGradientLayer layer];
//    NSArray *colors = [NSArray arrayWithObjects:
//                       (id)[[UIColor colorWithWhite:0 alpha:0] CGColor],
//                       (id)[[UIColor colorWithWhite:0 alpha:0.5] CGColor],
//                       (id)[[UIColor colorWithWhite:0 alpha:1] CGColor],
//                       nil];
    
    NSArray *colors = [NSArray arrayWithObjects:
                       (id)[[UIColor colorWithWhite:1 alpha:0.8]CGColor],
//                       (id)[[UIColor colorWithWhite:1 alpha:0.4]CGColor],
//                       (id)[[UIColor colorWithWhite:1 alpha:0.2]CGColor],
                       (id)[[UIColor colorWithWhite:1 alpha:0]CGColor],
                       nil];
    [gradLayer setColors:colors];
    //渐变起止点，point表示向量
    [gradLayer setStartPoint:CGPointMake(0.0f, 0.0f)];
    [gradLayer setEndPoint:CGPointMake(0.0f, 1.0f)];
    
    [gradLayer setFrame:bounds];
    return gradLayer;
}


#define PI 3.1415926
+ (double)LantitudeLongitudeDist:(double)lon1 other_Lat:(double)lat1 self_Lon:(double)lon2 self_Lat:(double)lat2
{
    double er = 6378137; // 6378700.0f;
    //ave. radius = 6371.315 (someone said more accurate is 6366.707)
    //equatorial radius = 6378.388
    //nautical mile = 1.15078
    double radlat1 = PI*lat1/180.0f;
    double radlat2 = PI*lat2/180.0f;
    //now long.
    double radlong1 = PI*lon1/180.0f;
    double radlong2 = PI*lon2/180.0f;
    if( radlat1 < 0 ) radlat1 = PI/2 + fabs(radlat1);// south
    if( radlat1 > 0 ) radlat1 = PI/2 - fabs(radlat1);// north
    if( radlong1 < 0 ) radlong1 = PI*2 - fabs(radlong1);//west
    if( radlat2 < 0 ) radlat2 = PI/2 + fabs(radlat2);// south
    if( radlat2 > 0 ) radlat2 = PI/2 - fabs(radlat2);// north
    if( radlong2 < 0 ) radlong2 = PI*2 - fabs(radlong2);// west
    //spherical coordinates x=r*cos(ag)sin(at), y=r*sin(ag)*sin(at), z=r*cos(at)
    //zero ag is up so reverse lat
    double x1 = er * cos(radlong1) * sin(radlat1);
    double y1 = er * sin(radlong1) * sin(radlat1);
    double z1 = er * cos(radlat1);
    double x2 = er * cos(radlong2) * sin(radlat2);
    double y2 = er * sin(radlong2) * sin(radlat2);
    double z2 = er * cos(radlat2);
    double d = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
    //side, side, side, law of cosines and arccos
    double theta = acos((er*er+er*er-d*d)/(2*er*er));
    double dist  = theta*er;
    return dist;
}

/**
 用户当前的经度
 
 @return 经度
 */
+ (double)userCurrentLongitude
{
    double localLng = 0.0;
//    double localLat = 0.0;
    NSDictionary *dict = [self objectForKey:KuserDefaultsLocation];
    if (dict.allKeys.count >= 2)
    {
        localLng = [dict[@"lng"] doubleValue];
//        localLat = [dict[@"lat"] doubleValue];
    }
    return localLng;
}

/**
 用户当前的纬度
 
 @return 纬度
 */
+ (double)userCurrentLatitude
{
//    double localLng = 0.0;
    double localLat = 0.0;
    
    NSDictionary *dict = [self objectForKey:KuserDefaultsLocation];
    if (dict.allKeys.count >= 2)
    {
//        localLng = [dict[@"lng"] doubleValue];
        localLat = [dict[@"lat"] doubleValue];
    }
    return localLat;
}

+ (NSMutableAttributedString *)attributeTitle:(NSString *)title titleColor:(UIColor *)titleColor titleFont:(UIFont *)titleFont value:(NSString *)value valueColor:(UIColor *)valueColor valueFont:(UIFont *)valueFont
{
    NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] init];
    NSAttributedString *name = [[NSAttributedString alloc] initWithString:title attributes:@{NSForegroundColorAttributeName:titleColor, NSFontAttributeName:titleFont}];
    [attr appendAttributedString:name];
    
    
    name = [[NSAttributedString alloc] initWithString:value attributes:@{NSForegroundColorAttributeName:valueColor, NSFontAttributeName:valueFont}];
    [attr appendAttributedString:name];
    
    return attr;
}

/**
 * @brief 把缓冲数据存储到本地
 * @param arckey 键
 * @param filename 文件名
 * @param data 存储到制定文件中的对象
 */
+ (void)writeCacheDataLocalKey:(NSString *)arckey saveFilename:(NSString *)filename saveid:(id)data
{
    NSMutableData *mutdata = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mutdata];
    [archiver encodeObject:data forKey:arckey];
    [archiver finishEncoding];
    [mutdata writeToFile:[NSFileManager fileDocumentPath:filename] options:NSDataWritingFileProtectionComplete error:nil];
//    [mutdata writeToFile:[NSFileManager getFilePath:filename] atomically:YES];
//    CC_SAFE_RELEASE_NULL(archiver);
//    CC_SAFE_RELEASE_NULL(mutdata);
}

/**
 * @brief 从本地读取缓存里面的数据
 * @param arckey 键
 * @param filename 文件名
 */
+ (id)readCacheDataLocalKey:(NSString *)arckey saveFilename:(NSString *)filename
{
    id calid = nil;
    if ([NSFileManager isPathFileExit:[NSFileManager fileDocumentPath:filename]])
    {
        NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[NSFileManager fileDocumentPath:filename]];
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
        calid = [unarchiver decodeObjectForKey:arckey];
        [unarchiver finishDecoding];
    }
    return calid;
}

/**
 * @brief 删除缓存里面的数据
 * @param arckey 键
 * @param filename 文件名
 */
+ (void)removeCacheDataLocalKey:(NSString *)arckey fileName:(NSString *)filename
{
    if ([NSFileManager isPathFileExit:[NSFileManager fileDocumentPath:filename]])
    {
        [[NSFileManager defaultManager] removeItemAtPath:[NSFileManager fileDocumentPath:filename] error:nil];
    }
}


//保存Cookie
+ (void)saveCookies
{
    NSData*cookiesData = [NSKeyedArchiver archivedDataWithRootObject:[[NSHTTPCookieStorage sharedHTTPCookieStorage]cookies]];
    [self setObject:cookiesData forKey:@"org.skyfox.cookie"];
}

/**
 加载Cookie 一般都是app刚刚启动的时候
 */
+ (void)loadCookies
{
    NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:@"org.skyfox.cookie"]];
    
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    
    for (NSHTTPCookie *cookie  in cookies) {
        [cookieStorage setCookie:cookie];
    }
}

/**
 将字符串转成数字
 
 @param strNum @"22"
 @return return value description
 */
+ (NSInteger)stringChangeDigital:(NSString *)strNum
{
    if ([strNum isAllNum])
    {
        return [strNum integerValue];
    }
    return 0;
}

/**
 拨打电话
 
 @param mobile 电话
 */
+ (void)actioinCall:(NSString *)mobile
{
//    NSMutableString *str=[[NSMutableString alloc] initWithFormat:@"telprompt://%@",mobile];
//    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];
//openURL:options:completionHandler
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"tel:%@", mobile]];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
    }
}

/**
 加入缓存
 
 @param object 缓存对象
 @param key key
 */
+ (void)addCacheObject:(id)object forKey:(NSString *)key
{
    [[YYCache cacheWithName:@"com.cn.zh_liaoshenjudicial"] setObject:object forKey:key];;
}

/**
 得到缓存数据
 
 @param key key description
 @return return value description
 */
+ (id)getCacheObject:(NSString *)key
{
    id obj = [[YYCache cacheWithName:@"com.cn.zh_liaoshenjudicial"] objectForKey:key];
    return obj;
}

/**
 删除指定的缓存
 
 @param key key
 */
+ (void)removeCacheKey:(NSString *)key
{
    if ([objectNull(key) isEqualToString:@""])
    {
        return;
    }
    [[YYCache cacheWithName:@"com.cn.zh_liaoshenjudicial"] removeObjectForKey:key];
}


+ (YYWebImageManager *)avatarImageManager
{
    static YYWebImageManager *manager;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSString *path = [[UIApplication sharedApplication].cachesPath stringByAppendingPathComponent:@"schoolcoach.avatar"];
        YYImageCache *cache = [[YYImageCache alloc] initWithPath:path];
        manager = [[YYWebImageManager alloc] initWithCache:cache queue:[YYWebImageManager sharedManager].queue];
        manager.sharedTransformBlock = ^(UIImage *image, NSURL *url) {
            if (!image) return image;
            return [image imageByRoundCornerRadius:100]; // a large value
        };
    });
    return manager;
}

+ (NSRegularExpression *)regexAt
{
    static NSRegularExpression *regex;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 微博的 At 只允许 英文数字下划线连字符，和 unicode 4E00~9FA5 范围内的中文字符，这里保持和微博一致。。
        // 目前中文字符范围比这个大
        regex = [NSRegularExpression regularExpressionWithPattern:@"@[-_a-zA-Z0-9\u4E00-\u9FA5]+" options:kNilOptions error:NULL];
    });
    return regex;
}

+ (NSRegularExpression *)regexEmoticon
{
    static NSRegularExpression *regex;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        regex = [NSRegularExpression regularExpressionWithPattern:@"\\[[^ \\[\\]]+?\\]" options:kNilOptions error:NULL];
    });
    return regex;
}

+ (NSDictionary *)emoticonDic
{
    static NSMutableDictionary *dic;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSString *emoticonBundlePath = [[NSBundle mainBundle] pathForResource:@"EmoticonWeibo" ofType:@"bundle"];
        dic = [self _emoticonDicFromPath:emoticonBundlePath];
    });
    return dic;
}

+ (NSMutableDictionary *)_emoticonDicFromPath:(NSString *)path
{
    NSMutableDictionary *dic = [NSMutableDictionary new];
    /*WBEmoticonGroup *group = nil;
    NSString *jsonPath = [path stringByAppendingPathComponent:@"info.json"];
    NSData *json = [NSData dataWithContentsOfFile:jsonPath];
    if (json.length) {
        group = [WBEmoticonGroup modelWithJSON:json];
    }
    if (!group) {
        NSString *plistPath = [path stringByAppendingPathComponent:@"info.plist"];
        NSDictionary *plist = [NSDictionary dictionaryWithContentsOfFile:plistPath];
        if (plist.count) {
            group = [WBEmoticonGroup modelWithJSON:plist];
        }
    }
    for (WBEmoticon *emoticon in group.emoticons) {
        if (emoticon.png.length == 0) continue;
        NSString *pngPath = [path stringByAppendingPathComponent:emoticon.png];
        if (emoticon.chs) dic[emoticon.chs] = pngPath;
        if (emoticon.cht) dic[emoticon.cht] = pngPath;
    }
    
    NSArray *folders = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
    for (NSString *folder in folders) {
        if (folder.length == 0) continue;
        NSDictionary *subDic = [self _emoticonDicFromPath:[path stringByAppendingPathComponent:folder]];
        if (subDic) {
            [dic addEntriesFromDictionary:subDic];
        }
    }*/
    return dic;
}

+ (UIImage *)imageWithPath:(NSString *)path
{
    if (!path) return nil;
    UIImage *image = [[self imageCache] objectForKey:path];
    if (image) return image;
    if (path.pathScale == 1) {
        // 查找 @2x @3x 的图片
        NSArray *scales = [NSBundle preferredScales];
        for (NSNumber *scale in scales) {
            image = [UIImage imageWithContentsOfFile:[path stringByAppendingPathScale:scale.floatValue]];
            if (image) break;
        }
    } else {
        image = [UIImage imageWithContentsOfFile:path];
    }
    if (image) {
        image = [image yy_imageByDecoded];
        [[self imageCache] setObject:image forKey:path];
    }
    return image;
}

+ (YYMemoryCache *)imageCache
{
    static YYMemoryCache *cache;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        cache = [YYMemoryCache new];
        cache.shouldRemoveAllObjectsOnMemoryWarning = NO;
        cache.shouldRemoveAllObjectsWhenEnteringBackground = NO;
        cache.name = @"WeiboImageCache";
    });
    return cache;
}

/**
 判断用户是否已经登录
 
 为了兼容学员端
 
 @return YES表示登录；NO表示没有登录
 */
+ (BOOL)isUserLogin
{
    if (![EDSAppDelegateTool sharedInstance].userInfoModel || [EDSAppDelegateTool sharedInstance].userInfoModel.loginState == 0)
    {
        return NO;
    }
    return YES;
}

/**
 把国测局的坐标转成百度的坐标
 
 @param latitude 国测局的经度
 @param longitude 经度
 @return 返回百度的坐标
 */
+ (CLLocationCoordinate2D)changePoints:(double)latitude longitude:(double)longitude
{
    CLLocationCoordinate2D cord;
    
    double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
    double x = longitude;
    double y = latitude;
    double z = sqrt(x * x + y * y) + 0.00002 * sin(y * x_pi);
    double theta = atan2(y, x) + 0.000003 * cos(x * x_pi);
    cord.longitude = z * cos(theta) + 0.0065;
    cord.latitude = z * sin(theta) + 0.006;
    
    return cord;
}


/**
 百度地图金纬度转高德地图经纬度
 
 @param coordinate 百度经纬度
 @return 返回高德地图经纬度
 */
+ (CLLocationCoordinate2D)getGaoDeCoordinateByBaiDuCoordinate:(CLLocationCoordinate2D)coordinate
{
    return CLLocationCoordinate2DMake(coordinate.latitude - 0.006, coordinate.longitude - 0.0065);
}

/**
 将高得地图经纬度转百度地图经纬度
 
 @param coordinate 高度经纬度
 @return 返回百度经纬度
 */
+ (CLLocationCoordinate2D)getBaiDuCoordinateByGaoDeCoordinate:(CLLocationCoordinate2D)coordinate
{
    return CLLocationCoordinate2DMake(coordinate.latitude + 0.006, coordinate.longitude + 0.0065);
}

+ (UIImage *)imageWithRotation:(UIImage *)image
{
//    UIDeviceOrientationPortrait
    UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
    debugLog(@"orientation=%zd", orientation);
    if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown)
    {
//        return [image imageByRotate:0 fitSize:YES];
        CGSize size = image.size;
        debugLogSizeName(@"size", size);
        if (size.width < size.height)
        {
            return [image imageByRotateLeft90];
        }
        return image;
    }
    else if (orientation == UIDeviceOrientationLandscapeLeft)
    {
        debugLog(@"左边");
        return [image imageByRotate:0 fitSize:YES];
    }
    else if (orientation == UIDeviceOrientationLandscapeRight)
    {
        debugLog(@"右边");
        return [image imageByRotate:0 fitSize:YES];
    }
    
    return image;
}

/// 业务提醒 当天 就返回时间(10:32)；昨天就返回昨天，其它返回日期
/// @param date 日期时间
+ (NSString *)formatBusinessReminderDate:(NSString *)date
{
    NSDate *now = [NSDate date];
    NSDate *inputDate = [NSDate dateWithString:date format:@"yyyy-MM-dd HH:mm:ss"];
    int ret = [now compareTime:inputDate format:@"yyyy-MM-dd"];
    if (ret == 0)
    {// 表示当天日期
        return [NSDate stringWithDateInOut:date inFormat:@"yyyy-MM-dd HH:mm:ss" outFormat:@"HH:mm"];
    }
    
//    daysWithDateStringDiffer
    NSInteger day = [NSDate daysWithDateStringDiffer:[inputDate stringWithFormat:@"yyyy-MM-dd"] endDate:[now stringWithFormat:@"yyyy-MM-dd"] format:@"yyyy-MM-dd"];
    if (day == 1)
    {
        return @"昨天";
    }
//    debugLog(@"day=%zd", day);
//    debugLog(@"ret=%d", ret);
    return [inputDate stringWithFormat:@"yyyy-MM-dd"];
}

/// 判断字符串中是否含有中文
/// @param string string description
+ (BOOL)isChineseChar:(NSString *)string
{
    BOOL ret = NO;
    for (int i=0; i<string.length; i++)
    {
        NSRange range = NSMakeRange(i, 1);
        NSString *subString = [string substringWithRange:range];
        const char *cString = [subString UTF8String];
        if (strlen(cString) == 3)
        {
            ret = YES;
            break;
        }
    }
    return ret;
}


+ (NSString *)getTmpFileUrl:(NSString *)url
{
    // http://192.168.0.133:9001/group1/M00/00/18/wKgAaF7Vu5-AVVBAAABaKj0d89A405.png
    if ([objectNull(url) isEqualToString:@""])
    {
        return @"";
    }
    
    if ([url hasPrefix:@"http"])
    {
        
        url = [url stringByReplacingOccurrencesOfString:@"http://" withString:@""];
        url = [url stringByReplacingOccurrencesOfString:@"https://" withString:@""];
        NSArray *list = [url componentsSeparatedByString:@"/"];
        NSString *firstUrl = list.firstObject;
        NSString *lastUrl = [url stringByReplacingOccurrencesOfString:firstUrl withString:@""];
        return [NSString stringWithFormat:@"%@%@", kImageBaseUrl, lastUrl];
         
//        return url;
    }
    return [NSString stringWithFormat:@"%@%@", kImageBaseUrl, url];
}


//获取字符串首字母(传入汉字字符串, 返回大写拼音首字母)
+ (NSString *)getFirstLetterFromString:(NSString *)aString
{
    //转成了可变字符串
    NSMutableString *str = [NSMutableString stringWithString:aString];
    //先转换为带声调的拼音
    CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformMandarinLatin,NO);
    //再转换为不带声调的拼音
    CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformStripDiacritics,NO);
    
    /*
     区： 音为ōu（欧）常有人读为“区”(qū)。
     查： 本是检查、考查的意思，念chá，但作为姓氏要念zhā。
     曾 指曾经、未曾之意时念céng,但作为姓氏时要念zēng。
     晟 本是光明之意，念shèng,。但作为姓氏时念chéng。
     单 本是不复杂、独一的意思，念dān，但是作为姓氏时念shàn。
     乐 是一个多音字，念lè或者yuè，作为姓氏时念yuè。
     仇 作姓氏时应读作qíu
     尉迟 其中的尉应读作yù
     沈 shen 也读chen 系统转换拼音时是chen
     */
#warning ===目前发现上面的这些作为姓氏的时候首字母与原汉字首字母不同需要特殊处理
    NSArray * chinacese = @[@"区",@"查",@"曾",@"晟",@"单",@"乐",@"仇",@"尉",@"沈"];
    NSArray * pinYin = @[@"ou",@"zha",@"zeng",@"cheng",@"shan",@"yue",@"qiu",@"yu",@"shen"];
    for (NSInteger i = 0; i<chinacese.count; i++) {
        if ([[(NSString *)aString substringToIndex:1] compare:chinacese[i]] == NSOrderedSame) {
            NSArray * arr = [str componentsSeparatedByString:@" "];
            if (arr.count) {
                [str replaceCharactersInRange:NSMakeRange(0, [arr[0] length]) withString:pinYin[i]];
                break;
            }
        }
    }
    //获取并返回首字母
    NSString *firstStr;
    //获取并返回首字母
    firstStr = [str substringToIndex:1];
    //判断是不是字母
    if ([self matchLetter:firstStr]) {
        //转化为大写字母
        NSString *strPinYin = [firstStr capitalizedString];
        return strPinYin;
    }else{
        //首字母不是字母返回#
        return @"#";
    }
}
#pragma mark 正则表达式
+ (BOOL)matchLetter:(NSString *)str
{
    //判断是否以字母开头
    NSString *ZIMU = @"^[A-Za-z]+$";
    NSPredicate *regextestA = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", ZIMU];
    
    if ([regextestA evaluateWithObject:str] == YES){
        return YES;
    }else{
        return NO;
    }
}

/// 显示错误提示视图
/// @param msg 信息
/// @param defMsg 默认信息
+ (void)showErrorTipView:(NSString *)msg defMsg:(NSString *)defMsg
{
    if ([objectNull(msg) isEqualToString:@""])
    {
        [SVProgressHUD showInfoWithStatus:defMsg];
    }
    else
    {
        [SVProgressHUD showInfoWithStatus:msg];
    }
}

+ (UIImage *)generateQRCodeWithString:(NSString *)string Size:(CGFloat)size
{
    //创建过滤器
    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    //过滤器恢复默认
    [filter setDefaults];
    //给过滤器添加数据<字符串长度893>
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    [filter setValue:data forKey:@"inputMessage"];
    //获取二维码过滤器生成二维码
    CIImage *image = [filter outputImage];
    UIImage *img = [self createNonInterpolatedUIImageFromCIImage:image WithSize:size];
    return img;
}

+ (UIImage *)createNonInterpolatedUIImageFromCIImage:(CIImage *)image WithSize:(CGFloat)size
{
    CGRect extent = CGRectIntegral(image.extent);
    CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
    
    //创建bitmap
    size_t width = CGRectGetWidth(extent)*scale;
    size_t height = CGRectGetHeight(extent)*scale;
    CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
    CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
    CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
    CGContextScaleCTM(bitmapRef, scale, scale);
    CGContextDrawImage(bitmapRef, extent, bitmapImage);
    
    //保存图片
    CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
    CGContextRelease(bitmapRef);
    CGImageRelease(bitmapImage);
    return [UIImage imageWithCGImage:scaledImage];
}

/// 查看字体库
+ (void)findFontName
{
    NSArray *familys = [UIFont familyNames];
    for (int i=0; i<familys.count; i++)
    {
        NSString *family = [familys objectAtIndex:i];
        debugLog(@"family = %@", family);
        
        NSArray *fonts = [UIFont fontNamesForFamilyName:family];
        for (int j=0; j<fonts.count; j++)
        {
            NSString *font = [fonts objectAtIndex:j];
            debugLog(@"font = %@", font);
        }
    }
}

/// 创建navBar 右边的按钮
/// @param title title description
/// @param titleColor titleColor description
/// @param action action description
+ (UIButton *)createNavBtnRight:(NSString *)title titleColor:(UIColor *)titleColor action:(SEL)action targetId:(nonnull id)targetId
{
    float width = [title widthForFont:[UIFont systemFontOfSize:14 weight:UIFontWeightMedium]] + 1;
    CGRect frame = CGRectMake(0, 0, width, 30);
    UIButton *btnRight = [UIButton createWithButton:nil frame:frame font:[UIFont systemFontOfSize:14 weight:UIFontWeightMedium] action:nil propertiesBlock:^(UIButton * _Nonnull button) {
        [button setTitle:title forState:UIControlStateNormal];
        if (titleColor)
        {
            [button setTitleColor:titleColor forState:UIControlStateNormal];
        }
        else
        {
            [button setTitleColor:[UIColor colorWithHexString:@"#ffffff"] forState:UIControlStateNormal];
        }
    }];
//    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:_btnRight];
//    self.navigationItem.rightBarButtonItem = item;
    [btnRight addTarget:targetId action:action forControlEvents:UIControlEventTouchUpInside];
    return btnRight;
}


/// 判断中英混合的的字符串长度
/// @param strtemp strtemp description
+ (int)convertToInt:(NSString *)strtemp
{
    int strlength = 0;
    for (int i=0; i< [strtemp length]; i++) {
        int a = [strtemp characterAtIndex:i];
        if( a > 0x4e00 && a < 0x9fff) { //判断是否为中文
            strlength += 2;
        }
    }
    return strlength;
}

/// //12小时之内是按小时，超过12小时按天，超过3天按日期
/// @param time time description
+ (NSString *)dateTimePraise:(NSString *)time
{
//    debugLog(@"time=%@", time);
    NSDate *now = [NSDate date];
    NSString *format = @"yyyy-MM-dd HH:mm:ss";
    NSString *nowStr = [now stringWithFormat:format];
    NSDate *date = [NSDate dateWithString:time format:format];
//    date = [date dateByAddingHours:-25];
    NSString *dateStr = [date stringWithFormat:format];
//    debugLog(@"date=%@", [date stringWithFormat:format]);
//    debugLog(@"now=%@", nowStr);
//    date=2021-08-22 20:49:28
//    now=2021-08-23 11:29:29
    // 小时
    long long hours = [NSDate hoursWithDateStringDiffer:dateStr endDate:nowStr format:format];
//    debugLog(@"minutes=%lld", hours);
    if (hours <= 12)
    {
        if (hours < 1)
        {
            long long minutes = [NSDate minutesWithDateStringDiffer:dateStr endDate:nowStr format:format];
            if (minutes < 30)
            {
                return @"刚刚";
            }
//            else if (minutes < 30)
//            {
//                return @"30分钟之内";
//            }
            hours = 1;
        }
        return [NSString stringWithFormat:@"%lld小时前", hours];
    }
    else if (hours <= (24 * 3) && hours > 12) // 三天
    {
        int day = 1;
        if (hours > 12 && hours <= 24)
        {
            day = 1;
        }
        else if (hours > 24 && hours <= 48)
        {
            day = 2;
        }
        else
        {
            day = 3;
        }
        return [NSString stringWithFormat:@"%d天前", day];
    }
    
    return [date stringWithFormat:@"yyyy/MM/dd"];
}

/// 判断手机号码格式是否正确
/// @param mobile mobile description
+ (BOOL)valiMobile:(NSString *)mobile
{
    mobile = [mobile stringByReplacingOccurrencesOfString:@" " withString:@""];
    if (mobile.length != 11)
    {
        return NO;
    }
    
    /**
     * 移动号段正则表达式
     */
    NSString *CM_NUM = @"^((13[4-9])|(147)|(15[0-2,7-9])|(178)|(18[2-4,7-8]))\\d{8}|(1705)\\d{7}$";
    /**
     * 联通号段正则表达式
     */
    NSString *CU_NUM = @"^((13[0-2])|(145)|(15[5-6])|(176)|(18[5,6]))\\d{8}|(1709)\\d{7}$";
    /**
     * 电信号段正则表达式
     */
    NSString *CT_NUM = @"^((133)|(153)|(177)|(191)|(18[0,1,9]))\\d{8}$";
    NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM_NUM];
    BOOL isMatch1 = [pred1 evaluateWithObject:mobile];
    NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU_NUM];
    BOOL isMatch2 = [pred2 evaluateWithObject:mobile];
    NSPredicate *pred3 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT_NUM];
    BOOL isMatch3 = [pred3 evaluateWithObject:mobile];

    if (isMatch1 || isMatch2 || isMatch3)
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

+ (NSString *)httpWithUrlDecode:(NSString *)url
{
    NSString *http = @"https://";
    if ([url hasPrefix:http])
    {
        url = [url stringByReplacingOccurrencesOfString:http withString:@""];
    }
    else
    {
        http = @"http://";
        if ([url hasPrefix:http])
        {
            url = [url stringByReplacingOccurrencesOfString:http withString:@""];
        }
        else
        {
            http = @"";
        }
    }
    NSString * urlStr = [NSString stringWithFormat:@"%@%@", http, [url stringByURLEncode]];
    return urlStr;
}

///// 写文件到本地
///// @param error error description
//+ (void)redirectLogToDocumentFolder:(NSString *)error
//{
//    NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
//
//    NSDateFormatter *dateformat = [[NSDateFormatter  alloc]init];
//    [dateformat setDateFormat:@"yyyy-MM-dd-HH-mm-ss"];
//    NSString *fileName = [NSString stringWithFormat:@"LOG-%@.txt",[dateformat stringFromDate:[NSDate date]]];
//    NSString *logFilePath = [documentDirectory stringByAppendingPathComponent:fileName];
//
//    // 先删除已经存在的文件
//    NSFileManager *defaultManager = [NSFileManager defaultManager];
//    [defaultManager removeItemAtPath:logFilePath error:nil];
//
//        // 将log输入到文件
////        freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stdout);
////NSStringEncoding
////        freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", [error cStringUsingEncoding:NSUTF8StringEncoding]);
//}

/// 分享
/// @param model model description
+ (void)showShared:(id)model
{
    /*
    @weakify(self);
    [UMSocialUIManager setPreDefinePlatforms:@[@(UMSocialPlatformType_WechatSession), @(UMSocialPlatformType_WechatTimeLine), @(UMSocialPlatformType_QQ), @(UMSocialPlatformType_Qzone)]];
    [UMSocialUIManager showShareMenuViewInWindowWithPlatformSelectionBlock:^(UMSocialPlatformType platformType, NSDictionary *userInfo) {
        @strongify(self);
        debugLog(@"platformType=%zd  == userInfo=%@", platformType, userInfo);
        [SVProgressHUD show];
        // 创建分享消息对象
        UMSocialMessageObject *msgObj = [UMSocialMessageObject messageObject];
        
        // 创建网页内容对象
//        NSString *thumurl = self.viewModel.infoModel.title_url;
        UMShareWebpageObject *shareObj = [UMShareWebpageObject shareObjectWithTitle:@"钣金联盟" descr:@"描述" thumImage:@"图片地址"];
        // http://111.39.245.157:8087/mobile/dynamic.html?id
        shareObj.webpageUrl = nil;//self.infoModel.content;
        msgObj.shareObject = shareObj;
        
        [[UMSocialManager defaultManager] shareToPlatform:platformType messageObject:msgObj currentViewController:self completion:^(id result, NSError *error) {
//            NSLog(@"result=%@", result);
//            UMSocialShareResponse *resp = result;
//            NSLog(@"msg=%@", resp.message);
            if (error)
            {
                [SVProgressHUD showInfoWithStatus:@"分享失败！"];
            }
            else
            {
                [SVProgressHUD showInfoWithStatus:@"分享成功！"];
            }
        }];
    }];
    
    // 5秒钟自行关闭旋转轮
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [SVProgressHUD dismiss];
    });
     */
}

/**
 发起分享

 @param platformType 分享平台类型
 @param model model description
 */
/*+ (void)sendShare:(UMSocialPlatformType)platformType model:(id)model vc:(UIViewController *)vc
{
    // 创建分享消息对象
    UMSocialMessageObject *msgObj = [UMSocialMessageObject messageObject];
    UMShareWebpageObject *shareObj = [UMShareWebpageObject shareObjectWithTitle:@"钣金联盟" descr:@"描述" thumImage:@"地址"];
    // 网页的url地址
    shareObj.webpageUrl = nil;//[NSString stringWithFormat:@"%@%zd", [EDSAppDelegateTool sharedInstance].htmlModel.communityURL, model.dynamicId];
    msgObj.shareObject = shareObj;
    [[UMSocialManager defaultManager] shareToPlatform:platformType messageObject:msgObj currentViewController:vc completion:^(id result, NSError *error) {
        debugLog(@"result=%@", result);
        debugLog(@"error=%@", [error localizedDescription]);
        if (error)
        {
            [SVProgressHUD showInfoWithStatus:@"分享失败！"];
        }
        else
        {
            [SVProgressHUD showInfoWithStatus:@"分享成功！"];
        }
    }];
}*/

/// 格式化
/// @param dateTime dateTime description
+ (NSString *)formatBalanceTime:(NSString *)dateTime
{
    NSDate *nowDate = [NSDate date];
    NSString *nowDateStr = [nowDate stringWithFormat:@"yyyy-MM-dd HH:mm:ss"];
//    debugLog(@"nowDate=%@; dateTime=%@", nowDateStr, dateTime);
    NSInteger minute = [NSDate minutesWithDateStringDiffer:dateTime endDate:nowDateStr format:@"yyyy-MM-dd HH:mm:ss"];
//    debugLog(@"minute=%zd", minute);
    if (minute < 1) {
        return @"刚刚";
    } else if (minute >= 1 && minute < 60) {
        return [NSString stringWithFormat:@"%zd分钟前", minute];
    } else if (minute >= 60 && minute < 60 * 24) {
        return [NSString stringWithFormat:@"%d小时候前", (int)(minute / 60)];
    }
    
    return [NSDate stringWithDateInOut:dateTime inFormat:@"yyyy-MM-dd HH:mm:ss" outFormat:@"yyyy/MM/dd HH:mm"];
}

+ (NSString *)parseUrl:(NSString *)url
{
    NSString *fileName = [url lastPathComponent];
    NSString *path = [url stringByDeletingLastPathComponent];
    NSString *urlStr = [NSString stringWithFormat:@"%@/%@", path, [fileName stringByURLEncode]];
    return urlStr;
}

/// 解码
/// @param url url description
+ (NSString *)parseWithDecode:(NSString *)url
{
    NSString *fileName = [url lastPathComponent];
    NSString *path = [url stringByDeletingLastPathComponent];
    NSString *urlStr = [NSString stringWithFormat:@"%@/%@", path, [fileName stringByURLDecode]];
    return urlStr;
}

/// 生成随机数
/// @param num 位数
+ (NSString *)generateTradeNO:(NSInteger)num
{
    NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    NSMutableString *resultStr = [[NSMutableString alloc] init];
    srand((unsigned)time(0));
    for (int i = 0; i < num; i++)
    {
        unsigned index = rand() % [sourceStr length];
        NSString *oneStr = [sourceStr substringWithRange:NSMakeRange(index, 1)];
        [resultStr appendString:oneStr];
    }
    return resultStr;
}

+ (void)drawLineOfDashByCAShapeLayer:(UIView *)lineView lineLength:(int)lineLength lineSpacing:(int)lineSpacing lineColor:(UIColor *)lineColor lineDirection:(BOOL)isHorizonal {

    CAShapeLayer *shapeLayer = [CAShapeLayer layer];

    [shapeLayer setBounds:lineView.bounds];

    if (isHorizonal) {

        [shapeLayer setPosition:CGPointMake(CGRectGetWidth(lineView.frame) / 2, CGRectGetHeight(lineView.frame))];

    } else{
        [shapeLayer setPosition:CGPointMake(CGRectGetWidth(lineView.frame) / 2, CGRectGetHeight(lineView.frame)/2)];
    }

    [shapeLayer setFillColor:[UIColor clearColor].CGColor];
    //  设置虚线颜色为blackColor
    [shapeLayer setStrokeColor:lineColor.CGColor];
    //  设置虚线宽度
    if (isHorizonal) {
        [shapeLayer setLineWidth:CGRectGetHeight(lineView.frame)];
    } else {

        [shapeLayer setLineWidth:CGRectGetWidth(lineView.frame)];
    }
    [shapeLayer setLineJoin:kCALineJoinRound];
    //  设置线宽，线间距
    [shapeLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithInt:lineLength], [NSNumber numberWithInt:lineSpacing], nil]];
    //  设置路径
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 0, 0);

    if (isHorizonal) {
        CGPathAddLineToPoint(path, NULL,CGRectGetWidth(lineView.frame), 0);
    } else {
        CGPathAddLineToPoint(path, NULL, 0, CGRectGetHeight(lineView.frame));
    }

    [shapeLayer setPath:path];
    CGPathRelease(path);
    //  把绘制好的虚线添加上来
    [lineView.layer addSublayer:shapeLayer];
}

/// 将秒转成 00:00
/// @param second second description
+ (NSString *)minuteSecondFormat:(NSInteger)second
{
    NSInteger minutes = second / 60;
    NSInteger seconds = second - minutes * 60;
    NSString *minuteStr = [NSString stringWithFormat:@"0%zd", minutes];
    if (minutes >= 10) {
        minuteStr = [NSString stringWithFormat:@"%zd", minutes];
    }
    NSString *secondStr = [NSString stringWithFormat:@"0%zd", seconds];
    if (seconds >= 10) {
        secondStr = [NSString stringWithFormat:@"%zd", seconds];
    }
    return [NSString stringWithFormat:@"%@:%@", minuteStr, secondStr];
}

/// 判断输入的是否是车牌号
/// @param carNumber carNumber description
+ (BOOL)isValidCarNumber:(NSString *)carNumber {
//    NSString *carNumberRegex = @"^[京津沪渝冀忌云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽赣贵粤青藏川宁鲁使领][A-Z][A-Z0-9]{4}[A-Z0-9 学 驾 警 港 澳]$";
    NSString *carNumberRegex = @"^(([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z](([0-9]{5}[ADF])|([ADF]([A-HJ-NP-Z0-9])[0-9]{4})))|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳使领]))$";
    NSPredicate *carNumberTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", carNumberRegex];
    // 只能判断普通的车牌号
    BOOL ret = [carNumberTest evaluateWithObject:carNumber];    
    return ret;
}

/// 判断是否是普通车牌号
/// @param carNumber carNumber description
+ (BOOL)isValidOrdinaryPlateNumber:(NSString *)carNumber {
    NSString *carNumberRegex = @"^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳使领]$";
    NSPredicate *carNumberTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", carNumberRegex];
    // 只能判断普通的车牌号
    BOOL ret = [carNumberTest evaluateWithObject:carNumber];
    return ret;
}

/// 判断是否是新能源车 车牌号
/// @param carNumber carNumber description
+ (BOOL)isValidNewEnergyPlateNumber:(NSString *)carNumber {
    NSString *carNumberRegex = @"^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z](([0-9]{5}[ADF])|([ADF]([A-HJ-NP-Z0-9])[0-9]{4}))$";
    NSPredicate *carNumberTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", carNumberRegex];
    // 只能判断普通的车牌号
    BOOL ret = [carNumberTest evaluateWithObject:carNumber];
    return ret;
}

/// 判断是否是vin码
/// @param vin vin description
+ (BOOL)isValidVIN:(NSString *)vin {
    NSString *pattern = @"^[A-Z0-9]{17}$";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
    return [predicate evaluateWithObject:vin];
}

/// 根据id得到名称
/// @param serFlow serFlow description
+ (NSString *)getServFlowName:(NSInteger)serFlow {
    // 服务流程 0.待分派 1.待接车 2.检查中 3.维修中 4.待报单 5.已完成 6.已取消 7.已关闭
    // 1.待接车 2.检查中 3.维修中 4.待报单 历史工单: 5.已完成 6.已关闭
    NSString *name = @"";
    switch (serFlow) {
        case 0:
            name = @"待抢单";
            break;
        case 1:
            name = @"待接车";
            break;
        case 2:
            name = @"检查中";
            break;
        case 3:
            name = @"维修中";
            break;
        case 4:
            name = @"待报单";
            break;
        case 5:
            name = @"已完成";
            break;
        case 6:
            name = @"已取消";
            break;
        case 7:
            name = @"已关闭";
            break;
        default:
            break;
    }
    return name;
}

/// 获取视频的第一帧的图片
/// @param videoURL 视频地址
/// @param iconImageView iconImageView description
+ (void)videoImageWithVideoURL:(NSURL *)videoURL imgView:(UIImageView *)iconImageView {
    // 先从缓存中查找是否有图片
    SDImageCache *cache = [SDImageCache sharedImageCache];
    UIImage *memoryImage = [cache imageFromMemoryCacheForKey:videoURL.absoluteString];
    if (memoryImage) {
        iconImageView.image = memoryImage;
        return;
    } else { // 从磁盘中查找是否有图片
        UIImage *diskImage = [cache imageFromDiskCacheForKey:videoURL.absoluteString];
        if (diskImage) {
            iconImageView.image = diskImage;
            return;
        }
    }
    
    // 如果都不存在，就开启异步线程下载图片
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
        NSParameterAssert(asset);
        AVAssetImageGenerator *assetImageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
        assetImageGenerator.appliesPreferredTrackTransform = YES;
        assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
        CGImageRef thumbnailImageRef = NULL;
        CFTimeInterval thumbnailImageTime = 1;
        NSError *error = nil;
        thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60) actualTime:NULL error:&error];
        if (!error) {
            debugLog(@"imageError=%@", [error localizedDescription]);
            UIImage *thumbnailImage = thumbnailImageRef ? [[UIImage alloc] initWithCGImage:thumbnailImageRef] : nil;
            
            dispatch_async(dispatch_get_main_queue(), ^{
                SDImageCache *cache = [SDImageCache sharedImageCache];
                [cache storeImage:thumbnailImage forKey:videoURL.absoluteString toDisk:YES completion:^{
                    
                }];
                iconImageView.image = thumbnailImage;
            });
        }
    });
}

+ (UIViewController *)cl_findBestViewController:(UIViewController *)vc{
    
    if (vc.presentedViewController) {
        
        // Return presented view controller
        return [self cl_findBestViewController:vc.presentedViewController];
        
    } else if ([vc isKindOfClass:[UISplitViewController class]]) {
        
        // Return right hand side
        UISplitViewController* svc = (UISplitViewController*) vc;
        if (svc.viewControllers.count > 0){
            return [self cl_findBestViewController:svc.viewControllers.lastObject];
        }else{
            return vc;
        }
    } else if ([vc isKindOfClass:[UINavigationController class]]) {
        
        // Return top view
        UINavigationController* svc = (UINavigationController*) vc;
        if (svc.viewControllers.count > 0){
            return [self cl_findBestViewController:svc.topViewController];
        }else{
            return vc;
        }
        
    } else if ([vc isKindOfClass:[UITabBarController class]]) {
        
        // Return visible view
        UITabBarController* svc = (UITabBarController*) vc;
        if (svc.viewControllers.count > 0){
            return [self cl_findBestViewController:svc.selectedViewController];
        }else{
            return vc;
        }
    } else {
        
        // Unknown view controller type, return last child view controller
        return vc;
        
    }
    
}

+ (UIViewController *)cl_currentViewController{
    
    // Find best view controller
    UIViewController *viewController = [UIApplication sharedApplication].keyWindow.rootViewController;
    
    return [self cl_findBestViewController:viewController];
    
}

/// 判断是不是 字母和数字的组合
/// - Parameter string: string description
+ (BOOL)isAlphaNumeric:(NSString *)password {
    /*
    NSString *regex = @"^[a-zA-Z0-9]+$";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    BOOL ret = [predicate evaluateWithObject:string];
    return ret;
     */
//    NSCharacterSet *alphanumericSet = [NSCharacterSet alphanumericCharacterSet];
//    NSRange nonAlphanumericRange = [string rangeOfCharacterFromSet:alphanumericSet.invertedSet];
//    return nonAlphanumericRange.location == NSNotFound;
    
    // 创建一个包含所有字母的字符集
    NSCharacterSet *letterSet = [NSCharacterSet letterCharacterSet];
    // 创建一个包含所有数字的字符集
    NSCharacterSet *numberSet = [NSCharacterSet decimalDigitCharacterSet];
    
    BOOL hasLetter = NO;
    BOOL hasNumber = NO;
    
    int letterNum = 0;
    int numicNum = 0;
    
    // 遍历字符串中的每个字符
    for (NSUInteger i = 0; i < password.length; i++) {
        unichar character = [password characterAtIndex:i];
        // 检查字符是否为字母
        if ([letterSet characterIsMember:character]) {
            hasLetter = YES;
            letterNum += 1;
        }
        // 检查字符是否为数字
        if ([numberSet characterIsMember:character]) {
            hasNumber = YES;
            numicNum += 1;
        }
        // 如果已经找到字母和数字，可以提前退出循环
//        if (hasLetter && hasNumber) {
//            break;
//        }
    }
    
    if (letterNum + numicNum != password.length) {
        return NO;
    }
    
    // 返回是否同时包含字母和数字
    return hasLetter && hasNumber;
}

@end
// business license





















